package cn.wkj.mall.common.ex.handler;

import cn.wkj.mall.common.ex.ServiceCode;
import cn.wkj.mall.common.ex.ServiceException;
import cn.wkj.mall.common.web.JsonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ConstraintViolationException;
import java.util.List;


@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 业务层主动抛出的异常
    @ExceptionHandler
    public JsonResult<Void> handleServiceException(ServiceException e) {
        log.debug("处理【ServiceException】异常");
        return JsonResult.fail(e);
    }

    // validation的参数校验异常
    @ExceptionHandler
    public JsonResult<Void> handleBindException(BindException e) {
        log.debug("处理BindException");

        Integer serviceCode = ServiceCode.ERR_BAD_REQUEST.getValue();

        StringBuilder messageBuilder = new StringBuilder();
        List<FieldError> fieldErrors = e.getFieldErrors();
        for (FieldError fieldError : fieldErrors) {
            messageBuilder.append(fieldError.getDefaultMessage());
        }

        String message = messageBuilder.toString();
        return JsonResult.fail(serviceCode, message);
    }
    // validation的参数校验异常
    @ExceptionHandler
    public JsonResult<Void> handleConstraintViolationException(ConstraintViolationException e) {
        log.debug("处理ConstraintViolationException");
        StringBuilder messageBuilder = new StringBuilder();
        Integer serviceCode = ServiceCode.ERR_BAD_REQUEST.getValue();
        e.getConstraintViolations().forEach(c -> messageBuilder.append(c.getMessage()));

        String message = messageBuilder.toString();
        return JsonResult.fail(serviceCode, message);
    }

    // validation的参数校验异常
    @ExceptionHandler()
    public JsonResult<Void> handleAccessDeniedException(AccessDeniedException e) {
        log.debug("处理AccessDeniedException");
        Integer serviceCode = ServiceCode.ERR_FORBIDDEN.getValue();
        String message = "请求失败,当前账号无此权限";
        return JsonResult.fail(serviceCode, message);

    }


    // 兜底异常
    @ExceptionHandler
    public JsonResult<Void> handleThrowable(Throwable e) {
        log.debug("处理【Throwable】异常");
        return JsonResult.fail(
                99999, "程序出现了未知错误！"
        );
    }
}
